
#include "textmode.h"
#include "utils/string.h"

tm_char* textmode_mem = 0; 
size_t terminal_row = 0; 
size_t terminal_col = 0; 

const tm_char textmode_make_char(const char c, const char color) 
{
    return (color << 8) | c; 
}

void textmode_terminal_init() 
{
    int i;
    textmode_mem = (tm_char*)(0xB8000); 
    terminal_row = 0; 
    terminal_col = 0; 
    
    for (i = 0; i < VGA_WIDTH * VGA_HEIGHT; i++) {
        textmode_mem[i] = textmode_make_char(' ', TEXTMODE_COLOR_BLACK);
    }
}

void textmode_put_char(const size_t x, const size_t y, const char symbol, const char color) 
{
    const size_t i = VGA_WIDTH * y + x; 
    const tm_char ch = textmode_make_char(symbol, color); 

    textmode_mem[i] = ch; 
}

void textmode_put_tm_char(const size_t x, const size_t y, const tm_char tm_symbol)
{
    const size_t i = VGA_WIDTH * y + x; 

    textmode_mem[i] = tm_symbol; 
}

void textmode_terminal_writechar(char symbol, char color)
{
    if (symbol == '\n') {
        terminal_row++; 
        terminal_col = 0; 
        return; 
    }

    textmode_put_char(terminal_col, terminal_row, symbol, color); 
    terminal_col++; 
    if (terminal_col == VGA_WIDTH) {
        terminal_col = 0; 
        terminal_row++;
    }
}

void print_colored(const char* string, const char color) 
{
    const size_t len = strlen(string); 
    int i; 
    
    for (i = 0; i < len; i++) {
        textmode_terminal_writechar(string[i], color); 
    }
}

void print(const char* string) 
{
    const size_t len = strlen(string); 
    int i; 
    
    for (i = 0; i < len; i++) {
        textmode_terminal_writechar(string[i], TEXTMODE_COLOR_WHITE); 
    }
}

void print_int(int num)
{
    char buf[32]; 
    char* buf_pos = buf; 
    int i = 0; 
    
    if (num < 0) {
        print("-");
        num = -num;
    }

    if (num > 0) {
        while (num > 0) {
            *buf_pos = (char)(num % 10); 
            num /= 10; 

            buf_pos++;
            i++; 
        }
    }
    else {
        *buf_pos = 0;

        buf_pos++; 
        i++; 
    }

    while (i-- > 0) {
        buf_pos--; 

        textmode_terminal_writechar(*buf_pos + '0', TEXTMODE_COLOR_WHITE);         
    }
}

void println_int(const int num) 
{
    print_int(num);
    textmode_terminal_writechar('\n', TEXTMODE_COLOR_WHITE); 
}